{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Numerical Python (numpy): arrays\n",
    "================================\n",
    "\n",
    "Numpy introduction\n",
    "------------------\n",
    "\n",
    "The NumPy package (read as NUMerical PYthon) provides access to\n",
    "\n",
    "-   a new data structure called `array`s which allow\n",
    "\n",
    "-   efficient vector and matrix operations. It also provides\n",
    "\n",
    "-   a number of linear algebra operations (such as solving of systems of linear equations, computation of Eigenvectors and Eigenvalues).\n",
    "\n",
    "### History\n",
    "\n",
    "Some background information: There are two other implementations that provide nearly the same functionality as NumPy. These are called “Numeric” and “numarray”:\n",
    "\n",
    "-   Numeric was the first provision of a set of numerical methods (similar to Matlab) for Python. It evolved from a PhD project.\n",
    "\n",
    "-   Numarray is a re-implementation of Numeric with certain improvements (but for our purposes both Numeric and Numarray behave virtually identical).\n",
    "\n",
    "-   Early in 2006 it was decided to merge the best aspects of Numeric and Numarray into the Scientific Python (<span>`scipy`</span>) package and to provide (a hopefully “final”) `array` data type under the module name “NumPy”.\n",
    "\n",
    "We will use in the following materials the “NumPy” package as provided by (new) SciPy. If for some reason this doesn’t work for you, chances are that your SciPy is too old. In that case, you will find that either “Numeric” or “numarray” is installed and should provide nearly the same capabilities.[5]\n",
    "\n",
    "### Arrays\n",
    "\n",
    "We introduce a new data type (provided by NumPy) which is called “`array`”. An array *appears* to be very similar to a list but an array can keep only elements of the same type (whereas a list can mix different kinds of objects). This means arrays are more efficient to store (because we don’t need to store the type for every element). It also makes arrays the data structure of choice for numerical calculations where we often deal with vectors and matricies.\n",
    "\n",
    "Vectors and matrices (and matrices with more than two indices) are all called “arrays” in NumPy.\n",
    "\n",
    "#### Vectors (1d-arrays)\n",
    "\n",
    "The data structure we will need most often is a vector. Here are a few examples of how we can generate one:\n",
    "\n",
    "-   Conversion of a list (or tuple) into an array using <span>`numpy.array`</span>:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[ 0.   0.5  1.   1.5]\n"
     ]
    }
   ],
   "source": [
    "import numpy as N\n",
    "x = N.array([0, 0.5, 1, 1.5])\n",
    "print(x)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "-   Creation of a vector using “ArrayRANGE”:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[ 0.   0.5  1.   1.5]\n"
     ]
    }
   ],
   "source": [
    "x = N.arange(0, 2, 0.5)\n",
    "print(x)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "-   Creation of vector with zeros"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[ 0.  0.  0.  0.]\n"
     ]
    }
   ],
   "source": [
    "x = N.zeros(4)\n",
    "print(x)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Once the array is established, we can set and retrieve individual values. For example:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[ 3.4  0.   4.   0. ]\n",
      "3.4\n",
      "[ 3.4  0.   4. ]\n"
     ]
    }
   ],
   "source": [
    "x = N.zeros(4)\n",
    "x[0] = 3.4\n",
    "x[2] = 4\n",
    "print(x)\n",
    "print(x[0])\n",
    "print(x[0:-1])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Note that once we have a vector we can perform calculations on every element in the vector with a single statement:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[ 0.   0.5  1.   1.5]\n",
      "[ 10.   10.5  11.   11.5]\n",
      "[ 0.    0.25  1.    2.25]\n",
      "[ 0.          0.47942554  0.84147098  0.99749499]\n"
     ]
    }
   ],
   "source": [
    "x = N.arange(0, 2, 0.5)\n",
    "print(x)\n",
    "print(x + 10)\n",
    "print(x ** 2)\n",
    "print(N.sin(x))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Matrices (2d-arrays)\n",
    "\n",
    "Here are two ways to create a 2d-array:\n",
    "\n",
    "-   By converting a list of lists (or tuples) into an array:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[1, 2, 3],\n",
       "       [4, 5, 6]])"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x = N.array([[1, 2, 3], [4, 5, 6]])\n",
    "x"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "-   Using the <span>`zeros`</span> method to create a matrix with 5 rows and 4 columns"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[ 0.,  0.,  0.,  0.],\n",
       "       [ 0.,  0.,  0.,  0.],\n",
       "       [ 0.,  0.,  0.,  0.],\n",
       "       [ 0.,  0.,  0.,  0.],\n",
       "       [ 0.,  0.,  0.,  0.]])"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x = N.zeros((5, 4))\n",
    "x"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The “shape” of a matrix can be queried like this (here we have 2 rows and 3 columns):"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[1 2 3]\n",
      " [4 5 6]]\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "(2, 3)"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x=N.array([[1, 2, 3], [4, 5, 6]])\n",
    "print(x)\n",
    "x.shape"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Individual elements can be accessed and set using this syntax:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "1"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x=N.array([[1, 2, 3], [4, 5, 6]])\n",
    "x[0, 0] "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x[0, 1]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "3"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x[0, 2]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "4"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x[1, 0]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([1, 4])"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x[:, 0]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([1, 2, 3])"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x[0,:]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Convert from array to list or tuple\n",
    "\n",
    "To create an array back to a list or tuple, we can use the standard python functions <span>`list(s)`</span> and <span>`tuple(s)`</span> which take a sequence <span>`s`</span> as the input argument and return a list and tuple, respectively:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([ 1,  4, 10])"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a = N.array([1, 4, 10])\n",
    "a"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[1, 4, 10]"
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "list(a)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(1, 4, 10)"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "tuple(a)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Standard Linear Algebra operations\n",
    "\n",
    "#### Maxtrix multiplication\n",
    "\n",
    "Two arrays can be multiplied in the usual linear-algebra way using <span>`numpy.matrixmultiply`</span>. Here is an example:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "import numpy as N\n",
    "import numpy.random       \n",
    "A = numpy.random.rand(5, 5)    # generates a random 5 by 5 matrix \n",
    "x = numpy.random.rand(5)       # generates a 5-element vector\n",
    "b=N.dot(A, x)                  # multiply matrix A with vector x "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Solving systems of linear equations\n",
    "\n",
    "To solve a system of equations *A***x** = **b** that is given in matrix form (*i.e* *A* is a matrix and **x** and **b** are vectors where *A* and **b** are known and we want to find the unknown vector **x**), we can use the linear algebra package (<span>`linalg`</span>) of <span>`numpy`</span>:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "import numpy.linalg as LA\n",
    "x = LA.solve(A, b)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Computing Eigenvectors and Eigenvalues\n",
    "\n",
    "Here is a small example that computes the \\[trivial\\] Eigenvectors and Eigenvalues (<span>`eig`</span>) of the unity matrix (<span>`eye`</span>)):"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[ 1.  0.  0.]\n",
      " [ 0.  1.  0.]\n",
      " [ 0.  0.  1.]]\n"
     ]
    }
   ],
   "source": [
    "import numpy\n",
    "import numpy.linalg as LA\n",
    "A = numpy.eye(3)     #'eye'->I->1 (ones on the diagonal)\n",
    "print(A)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[ 1.  1.  1.]\n"
     ]
    }
   ],
   "source": [
    "evalues, evectors = LA.eig(A)\n",
    "print(evalues)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[ 1.  0.  0.]\n",
      " [ 0.  1.  0.]\n",
      " [ 0.  0.  1.]]\n"
     ]
    }
   ],
   "source": [
    "print(evectors)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Note that each of these commands provides its own documentation. For example, <span>`help(LA.eig)`</span> will tell you all about the eigenvector and eigenvalue function (once you have imported `numpy.linalg` as `LA`)."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Curve fitting of polynomials\n",
    "\n",
    "Let’s assume we have x-y data to which we like to fit a curve (to minimise the least square deviation of the fit from the data).\n",
    "\n",
    "Numpy provides the routine <span>`polyfit(x,y,n)`</span> (which is similar to Matlab’s `polyfit` function which takes a list <span>`x`</span> of x-values for data points, a list <span>`y`</span> of y-values of the same data points and a desired order of the polynomial that will be determined to fit the data in the least-square sense as well as possible."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<matplotlib.text.Text at 0x10e616908>"
      ]
     },
     "execution_count": 23,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAYsAAAEPCAYAAACzwehFAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAIABJREFUeJzt3Xd8VVW+/vHPN6GFIgho6IgUERREECmiAYHQQYaeoMCo\n6FUc2x31N8PQxntH54pjVwYkNMFREIjUoIQmOCoC4tDEgAiIooBUCcn6/ZGoUQkngSQr55zn/Xrx\n4pSdnSdHPE/WXnvtY845REREziXCdwARESn8VBYiIhKQykJERAJSWYiISEAqCxERCUhlISIiAXkv\nCzObZGYHzGzTObZ51sx2mNkGM7umIPOJiEghKAtgMhCb3ZNm1hmo7ZyrCwwHXi6oYCIiksF7WTjn\nVgOHzrFJT2Bq5rbvA2XNLLogsomISAbvZZEDVYE9We7vzXxMREQKSDCUhYiIeFbEd4Ac2AtUz3K/\nWuZjv2FmutCViEguOecs0DaFpSws88/ZzAfuAV43sxbAYefcgex2pAsjZhg9ejSjR4/O0bYnU0+y\nfv96PvvuMw4cP8CBYwcy/s68/c2Jb4i0SKKKRlGyaEmiikQRVTSKqCJRlCtRjisqXMEVFa+gfsX6\n1KtQj5JFS+bvD5cLuXkdQp1ei5/ptfiZWcCeAApBWZjZa0AMUMHMvgBGAcUA55yb4JxbaGZdzOwz\n4Dgw1F/a4OecY8/3e1i7Zy1rv1zLe3ve49NvPqXBJQ2oX7E+lUpVonKZylxT6RqiS0cTXSqaiiUr\nku7SOXnmJCdST3Ay9eRPt787+R3bv93Om/95k60Ht7Lz0E6iS0VTv2J9mlZuSvvL29OqeiuKFynu\n+0cXkQvgvSycc4NysM29BZElVDnnWPvlWqZtnEbi9kRS01NpWa0lraq34qmOT9G0StM8Gw2kpaex\n6/Authzcwrov1/HoO4/yn2/+Q+vqrelweQfaX96eq6OvJsI0XSYSTCyUDtuYmQuln+dCJCcnU71R\ndaZvms60TdMoElGEwY0G069hP+qUr5PjoWdeOHTyEMt3LSdpZxLLUpbx/Q/f07dBX4ZcM4SmlZvm\na5bk5GRiYmLybf/BRK/Fz/Ra/MzMcjRnobIIMafOnGLaxmkkbExgx7c7GHDVAAY3GkyzKs0KtCDO\nZed3O5nxyQymbJxCVJEobmt8G/GN4qlcprLvaCJhR2URZk6nnebVj1/l8VWP0zi6MXc1u4vY2rEU\njSzqO1q2nHOs/mI1CRsSmLN1Dq2qt2LYNcPoVb8XkRGRF7TvlJTdjByZwN696VStGsG4cUOoVatm\n3gQXCSEqizBxJv0MUzdOZdzKcVxR4QrGth1L86rNfcfKteOnjzNnyxxe/uhlDhw7wB9b/5HbGt92\nXhPjKSm76dDhOXbuHAOUAo5Tu/YokpJGqDBEfkVlEeLS0tOYuXkmY1aMofpF1RnXdhyta7T2HStP\nrNq9iv9d/b9sPLCRB1o8wPCmwylTvEyOvz4+fgwzZjxMRlH86Dhxcf/H9Omj8jyvSDDLaVl4PxtK\ncu/j/R8zdN5QShcrzYRuE2hbq63vSHmqTc02tKnZhg1fbeCJNU9w+bOXc3ezu7nv+vuoWLJiwK/f\nuzedXxYFQCn27UvPl7wi4UDnLwaR02mn+cvyvxA7PZaHWj7EqqGrQq4osrqm0jXM/N1M1v5+LQeO\nHeDKF67k72v+zg9nfjjn11WtGkHGkpysjlOliv65i5wvHYYKEuv3r2fI3CHULFeTV7q9QpUyVXxH\nKnDbv93Ofyf9N58c+IQnOzzJ76783VnP8NKchUjOac4iRJxOO81fV/6Vlz98mac6PkV8o/hCcwqs\nL++mvMuDSx6kdLHSjI8df9YJ/R/Phtq3L50qVXQ2lEh2VBYhYPPXmxk0exCXlbuMV7q9onUIWaSl\npzFl4xT+/O6faVerHU92eDIsR1siFyqnZaGDuIXU/G3zaTelHQ+2fJB5A+bluChSUnYTHz+Gtm1H\nER8/hpSU3fmc1I/IiEiGNRnGtnu3UaNsDRq/3JiJ6yfqQpIi+UQji0LGOcffVv+NFz54gTn95+Rq\nzUQ4H6vfdGATw+YNo2yJskzoNoHa5Wv7jiQSFDSyCEKnzpxi8FuDmbN1Du/f/n6uF9eNHJmQpSgA\nSrFz5xhGjkzI66iFTqPoRqy7fR2d63Tm+onXM37teNLS03zHEgkZKotCYv/R/dyUcBNpLo2VQ1ZS\n9aLcf3JsuK8vKBJRhIdbPcy629cxf9t8Wr3ais1fb/YdSyQkqCwKgQ/3fUjzic3pUa8Hr/V+jaii\nUee1H60vyFCnfB3eve1dft/k97Sd0pan1z6tuQyRC6Q5C8+W7lxK3Jw4JnSbwC1X3nJB+wrnOYvs\npBxKYdCcQVxc4mISeiVwaalLfUcSKVR06mwQWPLZEuLfiuet/m9xQ40b8mSfWl/wW6lpqYxOHk3C\nxgQSeibQoXYH35FECg2VRSG3+LPFDH5rMHP7zw2ZCwAWdu+mvMutb91K3NVx/LXdXwv15dtFCorK\nohBbtGMRt829jbkD5tKqeivfccLKwRMHGTpvKAeOHWDm72bqFFsJezp1tpBauGMht829jXkD5qko\nPKhYsiLzB8wnvlE8LSe1ZMH2Bb4jiQQFjSwK0ILtCxg6byjzBsyjZfWWvuOEvbV71tL3jb4Mbzqc\nP934JyJMvztJ+NFhqELmx6KYP3A+Laq18B1HMu0/up8+b/ThkpKXMPWWqVxU/CLfkUQKlA5DFSLv\nf/k+Q+YNIXFgooqikKlcpjLLb1tOlTJVuH7i9Ww9uNV3JJFCSWWRz3Yd3sUtr9/CpB6TuL7a9b7j\nyFkUiyzGi11f5OGWD3Pj5BuZt3We70gihY4OQ+WjI6eO0PrV1tx+7e3c3+J+33EkB97/8n36vNEn\nYx6jzZ/C/rNDJPRpzsKz1LRUus3sRp2L6/B8l+f1phNE9h/dT/eZ3bnq0quY0H0CxSKL+Y4kkm80\nZ+GRc44Ri0YQaZE80/kZFUWQqVymMiuGrODwqcN0mt6JQycP+Y4k4p3KIh88ve5p3tvzHrP6zKJI\nRBHfceQ8lCpWitn9ZtM4ujGtXm3F54c+9x1JxCuVRR6bu3UuT619ircHva3TMINcZEQkT3d6mnuu\nu4fWr7Zm3ZfrfEcS8UZzFnlo/f71xE6PZVHcIppVaeYth+S9BdsXMGTeEF7s8iJ9G/b1HUckz2jO\nooAdOXWEvm/05YUuL6goQlDXel1ZGr+UB5Y8wLPvP+s7jkiB08giDzjnGDB7ABWiKvBi1xcL/PtL\nwdl1eBcdp3Wkf8P+jG07VicvSNDTyKIA/XP9P9l6cCvjY8f7jiL57LJyl7F62GoWfraQuxfcrc/5\nlrChkcUF+uTAJ7Sb2o5VQ1dRv2L9Av3e4s/3P3zPLa/fQvmo8ky/ZTrFixT3HUnkvGhkUQCOnz5O\nvzf78VTHp1QUYeai4hexYNAC0l06XV/rytEfjvqOJJKvNLK4AMPmDSPNpTGl15QC+55SuKSlp3H3\ngrv5+KuPWThoIZeUusR3JJFcCZqRhZl1MrOtZrbdzB45y/M3mdlhM1uf+efPPnL+2oxNM3hvz3u8\n0OUF31HEo8iISF7p9godL+9Im8lt2Pv9Xt+RRPKF1+XFZhYBPA/cDOwDPjCzec65X18neqVzrkeB\nB8zG9m+3c/+S+1k2eBmli5X2HUc8MzMev/lxLip+ETcl3MQ7t75DzXI1fccSyVO+RxbNgR3Oud3O\nuVRgFtDzLNsVmvMTfzjzA/3f7M/YmLE0rtTYdxwpRB654RFGNB/BTQk3sfO7nb7jiOQp32VRFdiT\n5f6XmY/9Wksz22BmC8ysQcFEO7vHVz1OzbI1uavZXT5jSCH1hxZ/4LEbHiNmSgzbDm7zHUckzwTD\nVe4+Amo4506YWWdgLlAvu41Hjx790+2YmBhiYmLyLMjGrzby8ocvs/GujVqMJdka3mw4xYsUp93U\ndiyJX8JVl17lO5LIT5KTk0lOTs7113k9G8rMWgCjnXOdMu8/Cjjn3BPn+JoUoKlz7ruzPJdvZ0Od\nST9Di4kt+K/r/othTYbly/eQ0DLzk5k8sOQBFsYt5NrK1/qOI3JWwXI21AdAHTOraWbFgAHA/Kwb\nmFl0ltvNySi43xRFfnt67dOUK1GOodcMLehvLUFq4NUDebHri3Se0Zl/7/237zgiF8TrYSjnXJqZ\n3QssJaO4JjnntpjZ8Iyn3QSgj5ndDaQCJ4H+BZ1zx7c7eGLNE/z7jn/r8JPkSu8re1MsshjdXuvG\ngkELuK7qdb4jiZwXLcoLIN2l025KO3rV76XP0ZbzlrgtkdsTb2fBoAW6KrEUKsFyGKrQm/DRBE6d\nOcWI5iN8R5Eg1v2K7kzoNoGur3Vl/f71vuOI5FownA3lzZ4jexi5fCTJtyUTGRHpO44EuZ71e5Lu\n0uk8ozOL4xbTpHIT35FEckxlkQ3nHHcvuJv7mt9Hw0sb+o4jIeKWK2/5qTCWxC/Rwk4JGiqLbMzc\nPJMvjnzBnP5zfEeREPO7Br8j3aUTOz2WpYOX0ii6ke9IIgGpLM7i8KnDPLjkQRIHJlIsspjvOBKC\n+jbs+1NhLBu8TKNXKfRUFmcxbsU4utfrrtMcJV/1v6o/Z9LPEDs9luQhydQpX8d3JJFsqSx+ZdvB\nbUzZOIVP/+tT31EkDMQ1iuNE6gnaT23PiiErdLVaKbRUFr/y0NKHePSGR4kuHR14Y5E8cEfTOzie\nepz209qzcshKKpep7DuSyG+oLLJY/Nlitn27TZPaUuDub3E/x09nFMaKISuoWLKi70giv6BFeZlS\n01J5YMkDPNXxKU1qixd/uvFP9LyiJx2ndeTwqcO+44j8gsoi00sfvkT1i6rTvV5331EkjD3e7nHa\n1GhDlxldOHb6mO84Ij/RtaGAgycO0uCFBiy/bblOYRTv0l06dybeyeeHPmdh3EJKFCnhO5KEsJxe\nG0plAdyz4B7MjOe7PJ8PqURyLy09jbg5cZw8c5LZ/WZTJELTi5I/VBY5tPnrzbSb0o4t92yhQskK\n+ZRMJPdOp52m56yeXFrqUib3nEyE6aix5D1ddTYHnHPcv/h+Rt44UkUhhU6xyGLM7jebnd/t5IHF\nDxBKv9hJ8Anrskjcnsi+o/u4q9ldvqOInFXJoiV5e9DbrNi9gnErx/mOI2EsbMsiLT2Nx955jL93\n+DtFI4v6jiOSrXIlyrEkfgnTNk3jufef8x1HwlTYzprN2jyLssXL0qVuF99RRAKKLh1N0uAk2kxu\nw8VRFxPfKN53JAkzYVkWqWmpjF4xmle6vaLP1JagcVm5y1gSv4R2U9pRtnhZul+hNUFScMLyMNTU\njVOpflF12tVq5zuKSK40uKQBiQMTGTZ/GKt2r/IdR8JI2JXFD2d+YOzKsYxrq8lCCU7XVb2O13q/\nRp83+rDpwCbfcSRMhF1ZTFw/kYaXNKR1jda+o4ictw61O/BMp2foMqMLKYdSfMeRMBBWcxYnUk/w\n+KrHSRyY6DuKyAUbcNUAvjn+DbHTY1k9bDWXlrrUdyQJYWE1snjpg5doUa0FTas09R1FJE+MuH4E\n/Rv2p8uMLhz94ajvOBLCwuZyH8dOH6POs3VIGpzE1dFXF3AykfzjnOOut+9i56GdLBi0gOJFivuO\nJEFEl/v4lWfff5Z2tdqpKCTkmBkvdn2RsiXKMvitwaSlp/mOJCEoLEYWh08dpu5zdVkzbA31KtTz\nkEwk/506c4rOMzrT8JKGPNf5Oa0hkhzRyCKL8WvH071edxWFhLQSRUowt/9cVn2xir+t/pvvOBJi\nQv5sqIMnDvLCBy/w0Z0f+Y4iku/KlijLorhFtH61NZXLVGbINUNISdnNyJEJ7N2bTtWqEYwbN4Ra\ntWr6jipBJuTL4tn3n6V3/d5cVu4y31FECkSVMlVYHLeYmxJuIu2o43+HfsrOnWOAUsBx1q0bRVLS\nCBWG5EpIz1kcO32MWs/U0lyFhKV1X64j5pWb+WHyAtgbk+WZ48TF/R/Tp4/yFU0KEc1ZkLFa+6aa\nN6koJCy1qNaCult6wMABUGFblmdKsW9furdcEpxCtixS01IZv3Y8j7R+xHcUEW8al6gP74yC+E5Q\nZl/mo8epUiVk/9eXfBKy/2Jmbp5JnfJ1uK7qdb6jiHgzbtwQan+/E9bfCnGdofg+atcexbhxQzwn\nk2ATkmWR7tJ5cs2TGlVI2KtVqyZJSSMYVMOomlaM6D/cwNuL79TktuSa97Iws05mttXMtpvZWd/d\nzexZM9thZhvM7JpA+1y4YyFFI4vSsXbHvA8sEmRq1arJjOmj2f3yOlpdew1jNo4i3WnOQnLHa1mY\nWQTwPBALNAQGmln9X23TGajtnKsLDAdeDrTfJ9Y8wSOtH9EKVpEsIiMimdF7BnuO7OGPSX/0HUeC\njO+RRXNgh3Nut3MuFZgF9PzVNj2BqQDOufeBsmYWnd0OY2//Pbu/202fBn3yK7NI0IoqGsX8gfNZ\nuGMhT6992nccCSK+y6IqsCfL/S8zHzvXNnvPss1Plh4/wMl36rFn9948CykSSspHlWdx/GLGrxvP\nrM2zfMeRIOG7LPJetQ85mDSLkSMTfCcRKbRqlK3BwkELuW/RfSxPWe47jgQB35f72AvUyHK/WuZj\nv96meoBtfvavBnDmedasWU5y8k3ExMTkUVSR0HJ19NW83ud1+r/Zn2W3LqNRdCPfkaQAJCcnk5yc\nnOuv83q5DzOLBLYBNwP7gX8DA51zW7Js0wW4xznX1cxaAP9wzrXIZn+OqG/hZHFdzkAkh17f/DoP\nJz3MmmFrqFG2RuAvkJCS08t9eB1ZOOfSzOxeYCkZh8QmOee2mNnwjKfdBOfcQjPrYmafAceBoefc\n6cnimYuORuR7fpFQ0P+q/uw/tp9O0zuxethqykeV9x1JCqGQu5BgXNxoXYJZ5Dw8vPRh1n25jqTB\nSUQVjfIdRwpITkcWIVcWofTziBSkdJdO/Jx4Tp05xRt93yAyItJ3JCkAuuqsiORKhEUwuedkjvxw\nhPsW3Yd+8ZKsVBYi8pPiRYozp98cVu9ZrY9mlV9QWYjIL/z40ayvfPQKUzZM8R1HCgnf6yxEpBCq\nUqYKi+IWETMlhkqlKxFbJ9Z3JPFMIwsROasrL7mSOf3mEP9WPB/u+9B3HPFMZSEi2WpdozX/7P5P\neszswWfffeY7jnikw1Aick696vfiwLEDdJreiTXD1hBdOtuLPksI08hCRAIa3mw4cVfH0fW1rhw7\nfcx3HPFAi/JEJEecc9yZeCdffP8FiQMTKRZZzHckyQNalCciecrMeKnbSxSPLM7t82/Xor0wo7IQ\nkRwrElGEWX1m8dl3n/Hoskd9x5ECpLIQkVwpWbQkiQMTmb99Pv9Y9w/fcaSA6GwoEcm1CiUrsCR+\nCa1fbU10qWgGXj3QdyTJZyoLETkvNcrWYFHcIm6eejMVSlagY+2OviNJPtJhKBE5b1ddehWz+80m\nfk48H+z9wHccyUcqCxG5IDfUuIFJPSbRY1YPtn+73XccyScBy8LMRpjZxQURRkSCU/cruvN4u8eJ\nnR7LvqP7fMeRfJCTkUU08IGZ/cvMOplZwMUbIhJ+hjUZxp3X3kmn6Z04fOqw7ziSx3K0gjuzIDoC\nQ4FmwL+ASc65nfkbL3e0glvEL+ccDyx5gPX717Mkfok+yzsI5OkK7sx34K8y/5wBLgbeNLMnLyil\niIQUM2N87Hiql61O/zf7k5qW6juS5JGAIwsz+wNwK3AQmAjMdc6lmlkEsMM5Vzv/Y+aMRhYihUNq\nWiq9Xu9FhagKJPRKIMJ0Lk1hlZcji/JAb+dcrHPuDedcKoBzLh3odoE5RSQEFY0syht93+DzQ5/z\n4JIHdR2pEKCrzopIvjl86jA3JdxE3wZ9+fONf/YdR85CV50VEe/KlSjHkvglJGxI4KUPXvIdRy6A\nLvchIvmqUulKLB28lBsn38jFURcz4KoBviPJeVBZiEi+u/ziy1kUt4j209pTtnhZOtft7DuS5JIO\nQ4lIgbg6+mrm9p/LbXNvY+Xulb7jSC6pLESkwLSs3pKZv5tJn3/10YUHg4zKQkQK1M2X38zEHhPp\nNrMbnxz4xHccySHNWYhIgetxRQ+Onz5OpxmdSL4tmboV6vqOJAGoLETEi4FXD+TY6WN0mNaBlUNX\nUqNsDd+R5BxUFiLizR1N7+DY6WO0n9qelUNXUql0Jd+RJBuasxARrx5o+QBxV8fRcVpHvj3xre84\nkg1d7kNEvHPO8ciyR3gn5R2WDV7GxVH6vLWCktPLfagsRKRQ+PGzMN7b8x5Jg5MoW6Ks70hhodCX\nReZHtb4O1AR2Af2cc0fOst0u4AiQDqQ655qfY58qC5Eg5pzj3oX3suHABhbHLaZM8TK+I4W8YLiQ\n4KPAMufcFcC7wGPZbJcOxDjnmpyrKEQk+JkZz3V5joaXNKTbzG4cP33cdyTJ5LMsegJTMm9PAXpl\ns52hiXiRsBFhEbzc7WUuv/hyeszqwYnUE74jCX7fhC91zh0AcM59BVyazXYOSDKzD8zsjgJLJyLe\nRFgEE7tPpHLpytzy+i2cOnPKd6Swl69zFmaWBERnfYiMN/8/AwnOufJZtv3WOVfhLPuo7Jzbb2aX\nAEnAvc651dl8P81ZiISQM+lniJsTx7HTx5jdbzYlipTwHSnkBMME9xYy5iIOmFklYLlz7soAXzMK\nOOqcG5/N827UqFE/3Y+JiSEmJiYPU4tIQUtNSyX+rXiOnDrCW/3fIqpolO9IQS05OZnk5OSf7o8Z\nM6bQl8UTwHfOuSfM7BHgYufco7/apiQQ4Zw7ZmalgKXAGOfc0mz2qZGFSAg6k36GW9+6lW9OfMO8\nAfMoWbSk70ghIxhGFuWBfwHVgd1knDp72MwqA/90znUzs1rAW2QcuioCzHDO/e0c+1RZiISotPQ0\nhs4byp7v95A4MJHSxUr7jhQSCn1Z5AeVhUhoS0tP447EO9jx3Q4WDlqodRh5IBjWWYiI5EpkRCQT\ne0ykQcUGxE6P5cip36zjlXyishCRoBJhEbzU7SWaVGpCx+kdOXzqsO9IYUFlISJBJ8IieL7L87Ss\n1pK2U9ry9fGvfUcKeSoLEQlKZsbTsU/To14P2kxuwxdHvvAdKaSpLEQkaJkZY9qO4e5md9Nmchu2\nHdzmO1LI0ifliUjQu7/F/ZQtXpaYKTEsHLSQJpWb+I4UcnTqrIiEjDlb5nDX23cxu99s2tRs4ztO\nUNCpsyISdnpf2ZsZvWfQ+1+9Wbhjoe84IUVlISIhpUPtDswfMJ+h84YyfdN033FChg5DiUhI+vTr\nT+nyWheGNx3OYzc8hlnAIy1hSZf7EJGwt+/oPrq+1pXmVZrzQtcXKBKhc3p+TWUhIgIc/eEofd7o\nQ9GIoszqM0sXIPwVTXCLiABlipfh7YFvc2mpS4lJiOGrY1/5jhSUVBYiEvKKRhZlUo9JdK/XnVaT\nWrH14FbfkYKODkOJSFhJ2JDAI8seYUbvGbS/vL3vON5pzkJEJBsrdq1gwOwBPHbDY4xoPiKsz5RS\nWYiInEPKoRR6zurJdVWu48WuL1K8SHHfkbzQBLeIyDnUurgW7/3+PQ7/cJi2U9pq4jsAlYWIhK3S\nxUrzRt83iK0dS/N/NuejfR/5jlRo6TCUiISNlJTdjByZwN696VStGsG4cUOoVasmkHERwuFvD+cf\nsf8grlGc36AFSHMWIiJZpKTspkOH59i5cwxQCjhO7dqjSEoa8VNhbDqwiT7/6kPMZTE80+kZoopG\nec1cEDRnISKSxciRCVmKAqAUO3eOYeTIhJ+2aRTdiI/u/Iijp49y/cTrtR4jC5WFiISFvXvT+bko\nflSKffvSf/FImeJleK33a9zb/F7aTG7DjE0zCixjYaayEJGwULVqBHD8V48ep0qV374Nmhl3Nr2T\nZYOXMXblWG6ffzsnUk8USM7CSmUhImFh3Lgh1K49ip8LI2POYty4Idl+TeNKjfnwjg85kXqC6yde\nz6dff5r/QQspTXCLSNj48WyoffvSqVLll2dDnYtzjlc/fpVH33mUh1s+zEOtHgqZy53rbCgRkTy2\n6/Aufj//9xw/fZyEXgnUr1jfd6QLprOhRETy2GXlLiNpcBK3Nr6VG169gafee4q09DTfsQqERhYi\nIudh53c7GTpvKOkunck9J1O3Ql3fkc6LRhYiIvmodvnaJA9Jpm+DvrSc1JJxK8Zx6swp37HyjcpC\nROQ8RVgEf2jxBz6880M+/upjGrzQgPnb5hOKRzh0GEpEJI8k7UzivsX3cVm5y3im0zPUq1DPd6SA\ndBhKRKSAdajdgY13baR9rfa0mtSKR5c9yrHTx3zHyhMqCxGRPFQsshgPtXqIT+7+hH1H91H3ubqM\nXzs+6FeA6zCUiEg+2nRgE2NXjGXNnjX8sdUfGd5sOCWLlvQd6ydalCciUohs/GojY1eO5b097xWq\n0ij0cxZm1sfMNptZmplde47tOpnZVjPbbmaPFGRGEZG80rhSY2b3m82iuEWs+mIVdZ6tw/+s+p+g\n+ThXn3MWnwC3ACuy28DMIoDngVigITDQzIJ/fb2IhK1rKl3DnP5zWBS3iJRDKVz5wpX0e6Mf73z+\nDukuPfAO8khKym7i48fkeHvvh6HMbDnwkHNu/VmeawGMcs51zrz/KOCcc09ksy8dhhKRoHLk1BGm\nb5rOKx+9wqkzpxjedDhDrhlChZIV8u17/vJTA0sX7sNQOVQV2JPl/peZj4mIhISyJcpyT/N72HjX\nRhJ6JbDp603UfrY2naZ34sUPXuSLI1/k+ff87acGBpav19g1syQgOutDgAP+5JxLzI/vOXr06J9u\nx8TEEBMTkx/fRkQkT5kZraq3olX1Vnz/w/cs3bmU+dvm85flf6HaRdXoXq873a/oTrMqzYiw8/89\nPzk5mdWr3yXjrTgX+XwftsnBYajRzrlOmfd1GEpEwkpaehprv1xL4rZEErcn8vXxr7m28rU0qdSE\nJpWb0KRSE+pWqJurAomPH8OMGQ+TMbIIklNnM8viYefcR2d5LhLYBtwM7Af+DQx0zm3JZl8qCxEJ\nafuO7uOngx1gAAAFk0lEQVTj/R/z8VeZf/Z/zDcnvqFRdCPqlK9D+RLlqVCyAhWiKvzi7/oV61Oi\nSAng/OYsvJWFmfUCngMqAoeBDc65zmZWGfinc65b5nadgGfImF+Z5Jz72zn2qbIQkbBz+NRhNny1\ngV2Hd/HtiW/59uS3P/+defvNfm/+4lpVP35q4IwZowt3WeQHlYWISO4U+kV5IiISPFQWIiISkMpC\nREQCUlmIiEhAKgsREQlIZSEiIgGpLEREJCCVhYiIBKSyEBGRgFQWIiISkMpCREQCUlmIiEhAKgsR\nEQlIZSEiIgGpLEREJCCVhYiIBKSyEBGRgFQWIiISkMpCREQCUlmIiEhAKgsREQlIZSEiIgGpLERE\nJCCVhYiIBKSyEBGRgFQWIiISkMpCREQCUlmIiEhAKgsREQlIZSEiIgGpLEREJCCVhYiIBKSyEBGR\ngFQWIiISkMpCREQC8lYWZtbHzDabWZqZXXuO7XaZ2UYz+9jM/l2QGUVEJIPPkcUnwC3AigDbpQMx\nzrkmzrnm+R8rNCQnJ/uOUCjodfiZXouf6bXIPW9l4Zzb5pzbAViATQ0dLss1/c+QQa/Dz/Ra/Eyv\nRe4Fw5uwA5LM7AMzu8N3GBGRcFQkP3duZklAdNaHyHjz/5NzLjGHu2ntnNtvZpeQURpbnHOr8zqr\niIhkz5xzfgOYLQcecs6tz8G2o4Cjzrnx2Tzv94cREQlCzrlA0wH5O7LIhbMGNbOSQIRz7piZlQI6\nAmOy20lOfmAREck9n6fO9jKzPUAL4G0zW5T5eGUzeztzs2hgtZl9DKwDEp1zS/0kFhEJX94PQ4mI\nSOEXDGdDBWRmncxsq5ltN7NHfOfxxcwmmdkBM9vkO4tvZlbNzN41s0/N7BMzu893Jl/MrLiZvZ+5\nsPWTzLm/sGZmEWa23szm+87iU24WPQf9yMLMIoDtwM3APuADYIBzbqvXYB6Y2Q3AMWCqc66R7zw+\nmVkloJJzboOZlQY+AnqG478LyJj/c86dMLNIYA1wn3MubK+IYGYPAE2Bi5xzPXzn8cXMPgeaOucO\nBdo2FEYWzYEdzrndzrlUYBbQ03MmLzJPKQ74Hz0cOOe+cs5tyLx9DNgCVPWbyh/n3InMm8XJOLEl\nuH9LvABmVg3oAkz0naUQyPGi51Aoi6rAniz3vySM3xTkt8zsMuAa4H2/SfzJPOzyMfAVkOSc+8B3\nJo+eBv6bMC7MLHK86DkUykIkW5mHoN4E/pA5wghLzrl051wToBpwvZk18J3JBzPrChzIHHUagS83\nFOpaO+euJWOkdU/moeyzCoWy2AvUyHK/WuZjEubMrAgZRTHNOTfPd57CwDn3PbAc6OQ7iyetgR6Z\nx+pnAm3NbKrnTN445/Zn/v0N8BYZh/XPKhTK4gOgjpnVNLNiwAAgnM9w0G9LP3sV+I9z7hnfQXwy\ns4pmVjbzdhTQAQjLiX7n3P9zztVwzl1OxnvFu865W33n8sHMSmaOvMmy6HlzdtsHfVk459KAe4Gl\nwKfALOfcFr+p/DCz14D3gHpm9oWZDfWdyRczaw3EAe0yTwtcb2bh+tt0ZWC5mW0gY95miXNuoedM\n4l+uFj0H/amzIiKS/4J+ZCEiIvlPZSEiIgGpLEREJCCVhYiIBKSyEBGRgFQWIiISkMpCREQCUlmI\niEhAKguRfGJmzTI/WKaYmZUys83hegE/CX5awS2Sj8xsLBCV+WePc+4Jz5FEzovKQiQfmVlRMi52\neRJo5fQ/nAQpHYYSyV8VgdJAGaCE5ywi500jC5F8ZGbzyPjchFpAFefcCM+RRM5LEd8BREKVmQ0G\nTjvnZplZBLDGzGKcc8meo4nkmkYWIiISkOYsREQkIJWFiIgEpLIQEZGAVBYiIhKQykJERAJSWYiI\nSEAqCxERCUhlISIiAf1/QI0WnQ64sUMAAAAASUVORK5CYII=\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x10b4b05f8>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "%matplotlib inline\n",
    "import numpy\n",
    "\n",
    "# demo curve fitting : xdata and ydata are input data\n",
    "xdata = numpy.array([0.0 , 1.0 , 2.0 , 3.0 , 4.0 , 5.0])\n",
    "ydata = numpy.array([0.0 , 0.8 , 0.9 , 0.1 , -0.8 , -1.0])\n",
    "# now do fit for cubic (order = 3) polynomial\n",
    "z = numpy.polyfit(xdata, ydata, 3)\n",
    "# z is an array of coefficients , highest first , i . e .\n",
    "#                 X^3            X^2          X             0\n",
    "# z = array ([ 0.08703704 , -0.81349206 , 1.69312169 , -0.03968254])\n",
    "# It is convenient to use ‘poly1d‘ objects for dealing with polynomials:\n",
    "p = numpy.poly1d(z) # creates a polynomial function p from coefficients\n",
    "                    # and p can be evaluated for all x then .\n",
    "\n",
    "# create plot\n",
    "xs = [0.1 * i for i in range (50)]\n",
    "ys = [p ( x ) for x in xs]   # evaluate p(x) for all x in list xs\n",
    "\n",
    "import pylab\n",
    "pylab.plot(xdata, ydata, 'o', label='data')\n",
    "pylab.plot(xs, ys, label='fitted curve')\n",
    "pylab.ylabel('y')\n",
    "pylab.xlabel('x')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "This shows the fitted curve (solid line) together with the precise computed data points."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### More numpy examples…\n",
    "\n",
    "…can be found here: <http://www.scipy.org/Numpy_Example_List>\n",
    "\n",
    "### Numpy for Matlab users\n",
    "\n",
    "There is a dedicated webpage that explains Numpy from the perspective of a (experienced) Matlab user at https://docs.scipy.org/doc/numpy-dev/user/numpy-for-matlab-users.html."
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.0"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}
